<template>
  <el-dialog
    v-model="props.dialogVisible"
    :title="props.title"
    width="600px"
    :before-close="() => emit('close')"
    @open="open"
  >
    <div>
      <el-form
        ref="formEl"
        :model="state.menuForm"
        label-width="80px"
        :rules="rules"
      >
        <el-form-item label="上级菜单">
          <el-tree-select
            style="width: 100%"
            v-model="state.menuForm.parentId"
            check-strictly
            :render-after-expand="false"
            :data="state.treeSelectList"
            :props="treeSelectProps"
            placeholder="请选择上级菜单"
          />
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-radio-group v-model="state.menuForm.menuType">
            <el-radio label="M">目录</el-radio>
            <el-radio label="C">菜单</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input
                v-model="state.menuForm.menuName"
                placeholder="请输入菜单名称"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="显示排序" prop="orderNum">
              <el-input
                v-model="state.menuForm.orderNum"
                type="number"
                placeholder="请输入显示排序"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="是否外链">
              <el-radio-group v-model="state.menuForm.isFrame">
                <el-radio label="0">是</el-radio>
                <el-radio label="1">否</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="路由地址" prop="path">
              <el-input
                v-model="state.menuForm.path"
                placeholder="请输入路由地址"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <template v-if="state.menuForm.menuType === 'C'">
          <el-row>
            <el-col :span="12">
              <el-form-item label="组件路径" prop="component">
                <el-input
                  v-model="state.menuForm.component"
                  placeholder="请输入组件路径"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="权限字符" prop="perms">
                <el-input
                  v-model="state.menuForm.perms"
                  placeholder="例如：system:menu:list"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12">
              <el-form-item label="路由参数">
                <el-input
                  v-model="state.menuForm.query"
                  placeholder="例如：{ id: 1, name: 'ry' }"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="是否缓存">
                <el-radio-group v-model="state.menuForm.isCache">
                  <el-radio label="0">缓存</el-radio>
                  <el-radio label="1">不缓存</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </template>

        <el-row>
          <el-col :span="12">
            <el-form-item label="显示状态">
              <el-radio-group v-model="state.menuForm.visible">
                <el-radio label="0">显示</el-radio>
                <el-radio label="1">隐藏</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单状态">
              <el-radio-group v-model="state.menuForm.status">
                <el-radio label="0">正常</el-radio>
                <el-radio label="1">停用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close">取消</el-button>
        <el-button type="primary" @click="confirm">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import {
  reactive,
  defineProps,
  defineEmits,
  ref,
  onMounted,
  defineExpose,
  nextTick,
} from 'vue'
import { addMenuFun, menuListFun, updateMenuFun } from '@/api/menu/index'
import { ElMessage } from 'element-plus'
// 声明触发父组件的方法
const emit = defineEmits(['close'])
// 声明接收过来的参数
const props = defineProps({
  isAdd: {
    type: Boolean,
    default: false,
  },
  dialogVisible: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
    default: '',
  },
})

// 树形选择器属性
const treeSelectProps = {
  value: 'menuId',
  label: 'menuName',
  children: 'children',
}
// 表单Ref
const formEl = ref()
// 表单校验数据
const rules = reactive({
  menuName: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
  orderNum: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
  path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
  component: [{ required: true, message: '组件路径不能为空', trigger: 'blur' }],
  perms: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
})
// 其他数据
const state = reactive({
  // 上级目录树形结构
  treeSelectList: [
    {
      menuId: 0,
      menuName: '主类目',
      children: [],
    },
  ],
  // 弹框表单
  menuForm: {
    parentId: 0, // 默认上级目录
    menuType: 'C', // 菜单类型,默认是菜单
    isFrame: '1', // 是否外链，默认否
    menuId: '',
    menuName: '',
    icon: '',
    orderNum: '',
    isCache: '0', // 默认缓存
    visible: '0', // 默认显示
    status: '0', // 默认正常
    path: '',
    perms: '',
    component: '',
  },
})

onMounted(() => {
  getMenuList()
})

// 弹框打开时的回调
const resetForm = (row) => {
  state.menuForm = {
    parentId: 0, // 默认上级目录
    menuType: 'C', // 菜单类型,默认是菜单
    isFrame: '1', // 是否外链，默认否
    menuId: '',
    menuName: '',
    icon: '',
    orderNum: '',
    isCache: '0', // 默认缓存
    visible: '0', // 默认显示
    status: '0', // 默认正常
    path: '',
    perms: '',
    component: '',
  }
  if (row) {
    if (props.isAdd && row.menuId) {
      state.menuForm.parentId = row.menuId
    } else {
      state.menuForm = JSON.parse(JSON.stringify(row))
    }
  }
}

// 默认查询菜单列表
const getMenuList = () => {
  menuListFun().then((res) => {
    state.treeSelectList[0].children = nestingMenu(res.data)
  })
}
// 递归一维菜单数据
const nestingMenu = (list) => {
  if (Array.isArray(list) && list.length > 0) {
    return list.reduce((prev, curr, i, arr) => {
      curr.children = arr.filter((item) => item.parentId === curr.menuId)
      if (curr.parentId === 0) {
        prev.push(curr)
      }
      return prev
    }, [])
  }
}

// 关闭弹框
const close = () => {
  emit('close')
}
// 确认按钮
const confirm = () => {
  // 先校验表单
  formEl.value.validate((valid, fields) => {
    if (valid) {
      if (state.menuForm.menuId) {
        updateMenuFun(state.menuForm).then((res) => {
          ElMessage.success('修改成功')
          emit('close', true)
        })
      } else {
        addMenuFun(state.menuForm).then((res) => {
          ElMessage.success('添加成功')
          emit('close', true)
        })
      }
    }
  })
}

// 导出需要被父组件调用的方法
defineExpose({
  resetForm,
})
</script>

<style scoped></style>
